package at.irian.jsfatwork.broker.domain.stock;

import at.irian.jsfatwork.broker.application.QuoteService;
import at.irian.jsfatwork.broker.application.StockService;
import at.irian.jsfatwork.broker.domain.DomainModelException;
import at.irian.jsfatwork.broker.domain.order.Order;
import at.irian.jsfatwork.broker.domain.order.OrderResponse;
import at.irian.jsfatwork.broker.util.JpaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.NoResultException;
import java.util.Iterator;
import java.util.List;

/**
 * @author Thomas Spiegl
 */
@Repository
public class StockExchange {

    @PersistenceContext
    private EntityManager em;

    @Autowired
    private QuoteService quoteService;

    @Autowired
    private StockService stockService;

    @SuppressWarnings({"unchecked"})
    public List<Stock> findStocks(String symbol) {
        Query query = em.createQuery("select s from Stock s where upper(s.symbol) like :symbol")
                .setParameter("symbol", JpaUtils.escapeWildcards(symbol.toUpperCase()) + "%");
        return query.getResultList();
    }

    public Stock findStockBySymbol(String symbol) {
        Query query = em.createQuery("select s from Stock s where s.symbol=:symbol");
        query.setParameter("symbol", symbol);
        try {
            return (Stock) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    public Stock createStock(String symbol) {
        Stock stock = new Stock();
        stock.setSymbol(symbol);
        em.persist(stock);
        return stock;
    }


    public Quote getQuote(Stock stock) {
        Quote quote = quoteService.getQuote(stock);
        if (quote == null) {
            throw new DomainModelException("No quote for stock (" + stock.getSymbol()  + ") found");
        }
        return quote;
    }


    public OrderResponse sendAndExecuteOrder(Order order) {
        return stockService.sendAndExecuteOrder(order);
    }


}